import React, { useEffect, useRef } from 'react';
import { message } from 'antd';
import Modal from 'src/components/Modal';
import StrategyNode from './strategy';
import CrossConfig from './cross';
import ChallengeNode from './challenge';
import ActionNode from './action';
import Flow from 'src/components/Flow';
import * as events from 'src/utils/event/componentEvent';
import { NODE } from 'src/components/Flow/utils/constants';
import { EDGE_TYPE } from 'src/utils/constant';
import { ADD_UNDO_MANAGER, eventEmitter } from 'src/components/Flow/utils/event';
import { randomKey } from '../../../../utils/utils';
import StrategyLog from './strategyLog';
import ActionLog from './actionLog';
import CrossLog from './crossLog';
import ChallengeLog from './challengeLog';

/**
 * @Method StrategyFlow 流程画布组件
 * @props {String} eventId 事件id
 * @props {Boolean} isResult 是否为执行结果展示，默认是undefined，即双击节点是配置节点弹窗，如果为true,则双击节点是弹出该节点的执行结果的右侧抽屉
 */
export default function StrategyFlow(props) {
  const { eventId, variable, operator, compareData, actions, using_variables } = props;
  console.log(props, 'flow');
  const _graph = useRef(); //画布对象
  const resultDetail = useRef();

  useEffect(() => {
    props.onRef && props.onRef(_graph.current);
    resultDetail.current = {};
  }, []);

  useEffect(() => {
    if (props.isResult) {
      events.eventEmitter.removeAllListeners(events.OPEN_STRATEGY_NODE_RESULT); //删除事件，避免重复绑定
      events.eventEmitter.removeAllListeners(events.OPEN_CHALLENGE_NODE_RESULT); //删除事件，避免重复绑定
      events.eventEmitter.removeAllListeners(events.OPEN_ACTION_NODE_RESULT); //删除事件，避免重复绑定
      events.eventEmitter.removeAllListeners(events.OPEN_CROSS_NODE_RESULT); //删除事件，避免重复绑定
      events.eventEmitter.on(events.OPEN_STRATEGY_NODE_RESULT, ({ data, actionType, modelTitle, sourceId }) => {
        openStrategyResult({ data, actionType, modelTitle, sourceId });
      });
      events.eventEmitter.on(events.OPEN_CHALLENGE_NODE_RESULT, ({ data, actionType, modelTitle, sourceId }) => {
        openChallengeResult({ data, actionType, modelTitle, sourceId });
      });
      events.eventEmitter.on(events.OPEN_ACTION_NODE_RESULT, ({ data, actionType, modelTitle, sourceId }) => {
        openActionResult({ data, actionType, modelTitle, sourceId });
      });
      events.eventEmitter.on(events.OPEN_CROSS_NODE_RESULT, ({ data, id }) => {
        openCrossResult({ data, id });
      });
    } else {
      events.eventEmitter.removeAllListeners(events.OPEN_STRATEGY_NODE); //删除事件，避免重复绑定
      events.eventEmitter.removeAllListeners(events.OPEN_CROSS_NODE); //删除事件，避免重复绑定
      events.eventEmitter.removeAllListeners(events.OPEN_CHALLENGE_NODE); //删除事件，避免重复绑定
      events.eventEmitter.removeAllListeners(events.OPEN_ACTION_NODE); //删除事件，避免重复绑定
      events.eventEmitter.on(
        events.OPEN_STRATEGY_NODE,
        ({ data, actionType, modelTitle, sourceId, nameDisabled, cumstomAction, isLimitMode }) => {
          openStrategyConfig({
            data,
            actionType,
            modelTitle,
            sourceId,
            nameDisabled,
            cumstomAction,
            isLimitMode,
          });
        },
      );
      events.eventEmitter.on(events.OPEN_CROSS_NODE, ({ data, actionType, modelTitle, sourceId }) => {
        console.log('fk', data);
        openCrossConfig({ data, actionType, modelTitle, sourceId });
      });

      events.eventEmitter.on(events.OPEN_ACTION_NODE, ({ data, actionType, modelTitle, sourceId }) => {
        openActionConfig({ data, actionType, modelTitle, sourceId });
      });
      events.eventEmitter.on(events.OPEN_CHALLENGE_NODE, ({ data, actionType, modelTitle, sourceId }) => {
        console.log('xxxx', data);
        openChallengeConfig({ data, actionType, modelTitle, sourceId });
      });
    }

    return () => {
      if (props.isResult) {
        events.eventEmitter.removeAllListeners(events.OPEN_STRATEGY_NODE_RESULT); //删除事件
        events.eventEmitter.removeAllListeners(events.OPEN_CHALLENGE_NODE_RESULT); //删除事件
        events.eventEmitter.removeAllListeners(events.OPEN_ACTION_NODE_RESULT); //删除事件
        events.eventEmitter.removeAllListeners(events.OPEN_CROSS_NODE_RESULT); //删除事件
      } else {
        events.eventEmitter.removeAllListeners(events.OPEN_STRATEGY_NODE);
        events.eventEmitter.removeAllListeners(events.OPEN_CROSS_NODE);
        events.eventEmitter.removeAllListeners(events.OPEN_CHALLENGE_NODE);
        events.eventEmitter.removeAllListeners(events.OPEN_ACTION_NODE);
      }
    };
  }, [eventId, variable, actions, operator, compareData]);

  // 打开分流配置弹窗
  function openCrossConfig({ data, actionType, modelTitle }) {
    const {
      x,
      y,
      type,
      shape,
      id,
      linkPoints,
      edge_type = EDGE_TYPE._CONDITION,
      edge_configs = [],
      compareData,
      isOld,
      isCompare,
      sourceNode,
      ...detail
    } = data;
    const outEdeges = sourceNode.getOutEdges();
    const edgeConfigs = outEdeges.map((item) => {
      const edge = item.getModel();
      const cur = edge_configs.find((it) => it.id === item.getModel().id);
      if (cur) {
        return {
          ...cur,
        };
      } else {
        const other = edge_type === EDGE_TYPE._CONDITION ? { condition_groups: [] } : { percent: 0 };
        return {
          id: edge.id,
          source: edge.source,
          target: edge.target,
          ...other,
        };
      }
    });

    const baseInfo = { x, y, type: shape, shape, id, linkPoints }; // 基础配置

    const modleId = Modal.open({
      title: modelTitle || '编辑分流条件',
      width: '800px',
      content: (
        <div className='stretegy-content'>
          <CrossConfig
            isCompare={isCompare}
            isOld={isOld}
            disabled={props.disabled}
            variable={variable}
            using_variables={using_variables}
            operator={operator}
            onUpdateNode={(config) => {
              updateNode({ ...baseInfo, ...detail, ...config }, () => Modal.close(modleId)); //更新节点
            }}
            onUpdateEdge={(item, config) => {
              console.log(config);
              updateEdge(item, { ...config }); // 更新线
            }}
            limitType={props.limitType}
            projectCode={props.projectCode}
            edge_type={edge_type}
            edge_configs={edgeConfigs}
            outEdeges={outEdeges}
            compareData={compareData}
            actionType={actionType}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开策略节点配置弹窗
  function openStrategyConfig({
    data,
    actionType,
    modelTitle,
    sourceId,
    nameDisabled,
    cumstomAction,
    isLimitMode = false,
  }) {
    // if (props.isCompare) {
    //   props.value.nodes.forEach((it, i) => {
    //     if (it.id === data.id) {
    //       index = i;
    //     }
    //   });
    // }
    // 新增cumstomAction参数，如果存在，则用自定义的action方法，否则就用内部的更新节点或者添加节点的action
    const action = cumstomAction
      ? cumstomAction
      : actionType === 'add' || actionType === 'copy'
      ? addNode
      : actionType === 'update'
      ? updateNode
      : null;
    const {
      x,
      y,
      type,
      shape,
      id,
      linkPoints,
      edge_type = EDGE_TYPE._CONDITION,
      edge_configs = [],
      compareData,
      isOld,
      isCompare,
      ...detail
    } = data;
    const baseInfo = { x, y, type: shape, shape, id, linkPoints }; // 基础配置
    const edgeConfig = { edge_type, edge_configs }; // 线配置
    // const compareDatax =
    //   (props.compareData && props.compareData.nodes && props.compareData.nodes.find((it) => it.id === id)) || {}; // 对比数据
    // console.log(compareData);
    const modleId = Modal.open({
      title: modelTitle || '新建规则节点',
      width: '1100px',
      content: (
        <div className='stretegy-content'>
          <StrategyNode
            isCompare={isCompare}
            isOld={isOld}
            disabled={props.disabled}
            nameDisabled={nameDisabled}
            operator={props.operator}
            appId={props.appId}
            eventId={props.eventId}
            importData={props.importData}
            onSubmit={(config) => action({ ...baseInfo, ...edgeConfig, ...config }, () => Modal.close(modleId))}
            sourceId={sourceId}
            value={Object.keys(detail).length > 0 ? { ...detail, id } : { ...detail }}
            compareData={compareData}
            actionType={actionType}
            close={() => Modal.close(modleId)}
            isLimitMode={isLimitMode}
            modes={props.strategy_mode}
            projectCode={props.projectCode}
            isImportant={props.isImportant}
            actions={props.actions}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开冠军挑战节点配置弹窗
  function openChallengeConfig({ data, actionType, modelTitle, sourceId }) {
    const {
      x,
      y,
      type,
      shape,
      id,
      linkPoints,
      nodes,
      edge_type = EDGE_TYPE._CONDITION,
      edge_configs = [],
      compareData,
      isOld,
      isCompare,
      ...detail
    } = data;
    const edgeConfig = { edge_type, edge_configs }; // 线配置
    console.log(nodes);
    // 新增cumstomAction参数，如果存在，则用自定义的action方法，否则就用内部的更新节点或者添加节点的action
    const action =
      actionType === 'add' || actionType === 'copy' ? addNode : actionType === 'update' ? updateNode : null;
    const baseInfo = { x, y, type: shape, shape, id, linkPoints };
    const modleId = Modal.open({
      title: modelTitle || '添加冠军挑战节点',
      width: '600px',
      content: (
        <div className='stretegy-content'>
          <ChallengeNode
            isCompare={isCompare}
            isOld={isOld}
            disabled={props.disabled}
            operator={props.operator}
            appId={props.appId}
            eventId={props.eventId}
            // importData={props.importData}
            onSubmit={(config) => action({ ...baseInfo, ...edgeConfig, ...config }, () => Modal.close(modleId))}
            sourceId={sourceId}
            value={{ nodes, ...detail }}
            compareData={compareData}
            actionType={actionType}
            modes={props.strategy_mode}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开动作节点配置弹窗
  function openActionConfig({ data, actionType, modelTitle, sourceId }) {
    // 新增cumstomAction参数，如果存在，则用自定义的action方法，否则就用内部的更新节点或者添加节点的action
    const action =
      actionType === 'add' || actionType === 'copy' ? addNode : actionType === 'update' ? updateNode : null;
    const {
      x,
      y,
      shape,
      name = '',
      id,
      linkPoints,
      edge_type = EDGE_TYPE._CONDITION,
      edge_configs = [],
      actions = [],
      compareData,
      isOld,
      isCompare,
    } = data;
    const baseInfo = { x, y, type: shape, shape, id, linkPoints }; // 基础配置
    const edgeConfig = { edge_type, edge_configs }; // 线配置
    console.log(actions, props.actions);
    const modelIds = randomKey();
    const modleId = Modal.open({
      title: modelTitle || '新建动作节点',
      width: '1100px',
      key: modelIds,
      content: (
        <div className='stretegy-content'>
          <ActionNode
            modelId={modelIds}
            isCompare={isCompare}
            isOld={isOld}
            onSubmit={(config) => action({ ...baseInfo, ...edgeConfig, ...config }, () => Modal.close(modleId))}
            compareData={compareData}
            close={() => Modal.close(modleId)}
            variable={props.variable}
            using_variables={using_variables}
            disabled={props.disabled}
            value={actions}
            name={name}
            sourceId={sourceId}
            actions={props.actions}
            isImportant={props.isImportant}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开策略节点的执行结果弹窗
  function openStrategyResult({ data }) {
    const { x, y, type, shape, id, linkPoints, variables, ...detail } = data;
    const { rules = [], strategy_id, version, comments } = detail.strategy_log || detail;

    const modleId = Modal.open({
      title: '规则节点日志',
      width: '1200px',
      content: (
        <div style={{ padding: '24px' }} className='stretegy-content'>
          <StrategyLog
            logs={
              detail.strategy_log && !comments
                ? {
                    ...detail.strategy_log,
                    rules: rules,
                    variables: variables || [],
                  }
                : {}
            }
            actions={props.actions}
            strategy_id={strategy_id}
            variable={props.variable}
            using_variables={using_variables}
            version={version}
            name={detail.name}
            comments={comments}
            close={() => Modal.close(modleId)}
            isImportant={props.isImportant}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开分流线的执行结果弹窗
  function openCrossResult({ data, id }) {
    const { edge_configs, edge_rule_result, variables } = data;
    let logs = {};
    const _curEdge = edge_configs.find((it) => it.id === id);
    if (!_curEdge.condition_groups) {
      message.warning('无日志');
      return;
    }
    if (edge_rule_result && edge_rule_result.id === id) {
      // 将后端的group日志打平成一维数组，生成[{id:'xxx',hit:true}]
      const rules = [];
      edge_rule_result.condition_group_results.forEach((group) => {
        rules.push({
          id: group.id,
          hit: group.hit,
        });
        group.simple_condition_results.forEach((it) => {
          rules.push({
            id: it.id,
            hit: it.hit,
          });
        });
      });
      logs = {
        variables: variables || [],
        rules: rules,
      };
    }

    const modleId = Modal.open({
      title: '分流日志',
      width: '1200px',
      content: (
        <div className='stretegy-content'>
          <CrossLog
            logs={logs}
            value={_curEdge}
            name={_curEdge.name}
            close={() => Modal.close(modleId)}
            variable={props.variable}
            using_variables={using_variables}
            operator={props.operator}
            disabled={true}
            isImportant={props.isImportant}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开策略节点的执行结果弹窗
  function openActionResult({ data }) {
    const { x, y, type, shape, id, linkPoints, variables, ...detail } = data;

    const modleId = Modal.open({
      title: '动作节点日志',
      width: '1200px',
      content: (
        <div className='stretegy-content'>
          <ActionLog
            logs={
              detail.action_rule_log
                ? {
                    rules: detail.action_rule_log,
                    variables: variables || [],
                  }
                : {}
            }
            actions={props.actions}
            value={detail.actions}
            name={detail.name}
            close={() => Modal.close(modleId)}
            isImportant={props.isImportant}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 打开挑战者节点的执行结果的右侧抽屉
  function openChallengeResult({ data }) {
    const { x, y, type, shape, id, linkPoints, variables, ...detail } = data;
    // if (!detail.challenge_node_log) {
    //   return;
    // }
    const modleId = Modal.open({
      title: '冠军挑战者节点日志',
      width: '1200px',
      content: (
        <div className='stretegy-content'>
          <ChallengeLog
            challenge_node_log={detail.challenge_node_log}
            variables={variables}
            using_variables={using_variables}
            nodes={detail.nodes}
            actions={props.actions}
            close={() => Modal.close(modleId)}
            isImportant={props.isImportant}
            variable={props.variable}
          />
        </div>
      ),
      maskClosable: false,
      isOkBtn: false,
      isCancelBtn: false,
    });
  }

  // 新增node
  function addNode(config, closeCallback) {
    const { sourceId, ...data } = config;

    const id = randomKey();
    _graph.current.addItem('node', { ...data });
    let label = '';
    // 如果sourceId 存在，则查找出他model信息
    if (sourceId) {
      const source = _graph.current.findById(sourceId);
      const { type } = source.getModel();

      // 如果是分流节点，则需要加入label+分流比例
      if (type === NODE._CROSS) {
        const outEdeges = source.getOutEdges();
        const outEdegesIndex = outEdeges.length;
        const totalPercent = outEdeges.reduce((total, it) => {
          total += it.getModel().percent || 0;
          return total;
        }, 0);
        label = `c${outEdegesIndex}`;
        _graph.current.addItem('edge', {
          source: sourceId,
          target: config.id,
          shape: 'line-arrow',
          label: label,
          percent: 100 - totalPercent >= 0 ? 100 - totalPercent : 0,
        });
      } else {
        _graph.current.addItem('edge', {
          source: sourceId,
          target: config.id,
          shape: 'line-arrow',
          id: id,
        });
      }
    }
    closeCallback && closeCallback();

    eventEmitter.emit(ADD_UNDO_MANAGER, {
      undo: function() {
        const item = _graph.current.findById(config.id);
        _graph.current.removeItem(item);
      },
      redo: function() {
        _graph.current.addItem('node', { ...data });
        sourceId &&
          _graph.current.addItem('edge', {
            source: sourceId,
            target: config.id,
            shape: 'line-arrow',
            label,
            id,
          });
      },
    });
  }

  // 更新node
  function updateNode(config, closeCallback) {
    const item = _graph.current.findById(config.id);
    const { sourceId, ...data } = config;
    _graph.current.update(item, { ...data });
    closeCallback && closeCallback();
  }

  // 更新Edge
  function updateEdge(item, config, closeCallback) {
    const { id, ...data } = config;
    _graph.current.update(item, { ...data });
    closeCallback && closeCallback();
  }

  function handleRef(ref) {
    _graph.current = ref;
    props.onRef && props.onRef(_graph.current);
  }

  return (
    <Flow
      {...props}
      wp={props.wp}
      disabled={props.disabled}
      graphicMode={props.graphicMode}
      value={props.value}
      onRef={(ref) => handleRef(ref)}
      onChangeMode={(value) => props.onChangeMode(value)}
      strategy_flow_mode={props.strategy_flow_mode}
      projectCode={props.projectCode}
      localSubmit={props.localSubmit}
    />
  );
}
